package com.rockcent.service.impl;

import com.rockcent.common.common.PageResult;
import com.rockcent.common.utils.ListSort;
import com.rockcent.mall.lib.domain.Category;
import com.rockcent.mall.lib.domain.Product;
import com.rockcent.mall.lib.domain.ProductCategories;
import com.rockcent.mall.lib.dto.ChannelDto;
import com.rockcent.mall.lib.dto.ChannelStatisticsChartDto;
import com.rockcent.mall.lib.repository.CategoryRepository;
import com.rockcent.mall.lib.repository.MerchantChannelStatisticsRepository;
import com.rockcent.mall.lib.repository.MerchantProductCategoriesRepository;
import com.rockcent.mall.lib.repository.MerchantProductRepository;
import com.rockcent.service.MerchantChannelStatisticsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by hone on 17-2-6.
 * 渠道统计
 */
@Service
public class MerchantChannelStatisticsServiceImpl implements MerchantChannelStatisticsService {

    @Autowired
    private MerchantChannelStatisticsRepository merchantChannelStatisticsRepository;

    @Autowired
    private CategoryRepository categoryRepository;

    @Autowired
    private MerchantProductRepository merchantProductRepository;

    @Autowired
    private MerchantProductCategoriesRepository merchantProductCategoriesRepository;

    /**
     * 访问次数
     * @param mallId
     * @param merchantId
     * @param startDate
     * @param endDate
     * @param typeIds
     * @param sourceType
     * @return
     */
    @Override
    public Long channelViewCount(Long mallId, Long merchantId, String startDate, String endDate, List<Long> typeIds, String sourceType, Long channelId) {
        return merchantChannelStatisticsRepository.channelViewCount(mallId,merchantId,startDate,endDate,typeIds,sourceType,channelId);
    }

    /**
     * 访问人数
     * @param mallId
     * @param merchantId
     * @param startDate
     * @param endDate
     * @param typeIds
     * @param sourceType
     * @param channelId
     * @return
     */
    @Override
    public Long channelViewCustomerCount(Long mallId, Long merchantId, String startDate, String endDate, List<Long> typeIds, String sourceType, Long channelId) {
        return merchantChannelStatisticsRepository.channelViewCustomerCount(mallId,merchantId,startDate,endDate,typeIds,sourceType,channelId);
    }

    /**
     * 销售数量
     * @param mallId
     * @param merchantId
     * @param startDate
     * @param endDate
     * @param typeIds
     * @param sourceType
     * @param channelId
     * @return
     */
    @Override
    public Long channelSaleCount(Long mallId, Long merchantId, String startDate, String endDate, List<Long> typeIds, String sourceType, Long channelId) {
        return merchantChannelStatisticsRepository.channelSaleCount(mallId,merchantId,startDate,endDate,typeIds,sourceType,channelId);
    }

    /**
     * 下单人数
     * @param mallId
     * @param merchantId
     * @param startDate
     * @param endDate
     * @param typeIds
     * @param sourceType
     * @param channelId
     * @return
     */
    @Override
    public Long channelOrderCustomerCount(Long mallId, Long merchantId, String startDate, String endDate, List<Long> typeIds, String sourceType, Long channelId) {
        return merchantChannelStatisticsRepository.channelOrderCustomerCount(mallId,merchantId,startDate,endDate,typeIds,sourceType,channelId);
    }

    /**
     * 核销数量
     * @param mallId
     * @param merchantId
     * @param startDate
     * @param endDate
     * @param typeIds
     * @param sourceType
     * @param channelId
     * @return
     */
    @Override
    public Long channelVerifyCount(Long mallId, Long merchantId, String startDate, String endDate, List<Long> typeIds, String sourceType, Long channelId) {
        return merchantChannelStatisticsRepository.channelVerifyCount(mallId,merchantId,startDate,endDate,typeIds,sourceType,channelId);
    }

    /**
     * 核销人数
     * @param mallId
     * @param merchantId
     * @param startDate
     * @param endDate
     * @param typeIds
     * @param sourceType
     * @param channelId
     * @return
     */
    @Override
    public Long channelVerifyCustomerCount(Long mallId, Long merchantId, String startDate, String endDate, List<Long> typeIds, String sourceType, Long channelId) {
        return merchantChannelStatisticsRepository.channelVerifyCustomerCount(mallId,merchantId,startDate,endDate,typeIds,sourceType,channelId);
    }

    /**
     * 访问次数 top 10
     * @param mallId
     * @param merchantId
     * @param startDate
     * @param endDate
     * @param typeIds
     * @param sourceType
     * @param groupBy
     * @param channelIds
     * @return
     */
    @Override
    public List<ChannelStatisticsChartDto> channelViewCount(Long mallId, Long merchantId, String startDate, String endDate, List<Long> typeIds, String sourceType, String groupBy, List<Long> channelIds) {
        return merchantChannelStatisticsRepository.channelViewCount(mallId,merchantId,startDate,endDate,typeIds,sourceType,groupBy,channelIds);
    }

    /**
     * 访问人数 top 10
     * @param mallId
     * @param merchantId
     * @param startDate
     * @param endDate
     * @param typeIds
     * @param sourceType
     * @param groupBy
     * @param channelIds
     * @return
     */
    @Override
    public List<ChannelStatisticsChartDto> channelViewCustomerCount(Long mallId, Long merchantId, String startDate, String endDate, List<Long> typeIds, String sourceType, String groupBy, List<Long> channelIds) {
        return merchantChannelStatisticsRepository.channelViewCustomerCount(mallId,merchantId,startDate,endDate,typeIds,sourceType,groupBy,channelIds);
    }

    /**
     * 销售数量 top 10
     * @param mallId
     * @param merchantId
     * @param startDate
     * @param endDate
     * @param typeIds
     * @param sourceType
     * @param groupBy
     * @param channelIds
     * @return
     */
    @Override
    public List<ChannelStatisticsChartDto> channelSaleCount(Long mallId, Long merchantId, String startDate, String endDate, List<Long> typeIds, String sourceType, String groupBy, List<Long> channelIds) {
        return merchantChannelStatisticsRepository.channelSaleCount(mallId,merchantId,startDate,endDate,typeIds,sourceType,groupBy,channelIds);
    }

    /**
     * 下单人数 top 10
     * @param mallId
     * @param merchantId
     * @param startDate
     * @param endDate
     * @param typeIds
     * @param sourceType
     * @param groupBy
     * @param channelIds
     * @return
     */
    @Override
    public List<ChannelStatisticsChartDto> channelOrderCustomerCount(Long mallId, Long merchantId, String startDate, String endDate, List<Long> typeIds, String sourceType, String groupBy, List<Long> channelIds) {
        return merchantChannelStatisticsRepository.channelOrderCustomerCount(mallId,merchantId,startDate,endDate,typeIds,sourceType,groupBy,channelIds);
    }

    /**
     * 核销数量 top 10
     * @param mallId
     * @param merchantId
     * @param startDate
     * @param endDate
     * @param typeIds
     * @param sourceType
     * @param groupBy
     * @param channelIds
     * @return
     */
    @Override
    public List<ChannelStatisticsChartDto> channelVerifyCount(Long mallId, Long merchantId, String startDate, String endDate, List<Long> typeIds, String sourceType, String groupBy, List<Long> channelIds) {
        return merchantChannelStatisticsRepository.channelVerifyCount(mallId,merchantId,startDate,endDate,typeIds,sourceType,groupBy,channelIds);
    }

    /**
     * 核销人数 top 10
     * @param mallId
     * @param merchantId
     * @param startDate
     * @param endDate
     * @param typeIds
     * @param sourceType
     * @param groupBy
     * @param channelIds
     * @return
     */
    @Override
    public List<ChannelStatisticsChartDto> channelVerifyCustomerCount(Long mallId, Long merchantId, String startDate, String endDate, List<Long> typeIds, String sourceType, String groupBy, List<Long> channelIds) {
        return merchantChannelStatisticsRepository.channelVerifyCustomerCount(mallId,merchantId,startDate,endDate,typeIds,sourceType,groupBy,channelIds);
    }

    /**
     * 查找渠道列表
     * @param page
     * @param mallId
     * @param merchantId
     * @param startDate
     * @param endDate
     * @param typeIds
     * @param sourceType
     * @param channelIds
     * @return
     */
    @Override
    public PageResult<ChannelStatisticsChartDto> findChannels(PageResult page, Long mallId, Long merchantId, String startDate, String endDate, List<Long> typeIds, String sourceType, List<Long> channelIds) {
        return merchantChannelStatisticsRepository.findChannels(page,mallId,merchantId,startDate,endDate,typeIds,sourceType,channelIds);
    }

    /**
     * 计算渠道产品品类数
     * @param mallId
     * @param merchantId
     * @param channelId
     * @return
     */
    @Override
    public Long computeChannelCategoryCount(Long mallId, Long merchantId, Long channelId) {
        List<ChannelStatisticsChartDto> channelProductCategories = merchantChannelStatisticsRepository.findChannelProductCategories(mallId,merchantId,channelId);
        Set<Long> dateSet = new HashSet<>();
        if(channelProductCategories!=null && channelProductCategories.size()>0) {
            for(ChannelStatisticsChartDto dto:channelProductCategories) {
                if(dto.getId()!=null && dto.getId().longValue()>0) {
                    Product product = merchantProductRepository.findOne(dto.getId());
                    if(product!=null) {
                        if(product.getMarketId()!=null && product.getMarketId().longValue()>0) {
                            product = merchantProductRepository.findOne(product.getMarketId());
                        }
                        List<ProductCategories> productCategories = merchantProductCategoriesRepository.findByProductId(product.getId());
                        if(productCategories!=null && productCategories.size()>0) {
                            Category category = findCategoryById(productCategories.get(0).getCategoryId());
                            if (category != null) {
                                dateSet.add(category.getId());
                            }
                        }
                    }
                }
            }
        }
        return new Long(dateSet.size());
    }

    /**
     * 查找
     * @param id
     * @return
     */
    private Category findCategoryById(Long id) {
        Category category = categoryRepository.findById(id);
        if(category!=null) {
            if(category.getParentId()!=null && category.getParentId().longValue()>0) {
                category=findCategoryById(category.getParentId());
            }
        }
        return category;
    }

    /**
     * 获取TOP5的活跃渠道
     * @param page
     * @param mallId
     * @param merchantId
     * @return
     */
    @Override
    public PageResult<ChannelDto> findTop5ActiveChannels(PageResult page, Long mallId, Long merchantId) {
        PageResult<ChannelDto> channels = merchantChannelStatisticsRepository.calculateChannelsViewCountAndSaleCount(page,mallId,merchantId);
        if(channels!=null) {
            List<ChannelDto> list = channels.data;
            int totalViewCount = 0;//总访问量
            int totalSaleCount = 0;//总销售量
            if(list!=null && list.size()>0) {
                for(ChannelDto dto:list) {
                    totalViewCount+=dto.getViewCount().intValue();
                    totalSaleCount+=dto.getSaleCount().intValue();
                }
                for(ChannelDto c:list) {
                    BigDecimal totalViewCountBig = new BigDecimal(totalViewCount);
                    BigDecimal totalSaleCountBig = new BigDecimal(totalSaleCount);
                    BigDecimal viewCount = new BigDecimal(c.getViewCount());
                    BigDecimal saleCount = new BigDecimal(c.getSaleCount());
                    BigDecimal viewRate = BigDecimal.valueOf(0);
                    BigDecimal saleRate = BigDecimal.valueOf(0);
                    if(totalViewCount!=0) {
                        //单个渠道访问量/商户所有渠道访问量*0.6
                        viewRate = viewCount.divide(totalViewCountBig, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(0.6));
                    }
                    if(totalSaleCount!=0) {
                        //单个渠道销售量/商户所有渠道总销量*0.4
                        saleRate = saleCount.divide(totalSaleCountBig, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(0.4));
                    }
                    c.setStar(viewRate.add(saleRate).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                }
                ListSort<ChannelDto> listSort = new ListSort<ChannelDto>();
                listSort.sort(list,"getStar","desc");
                int size = list.size()>5?5:list.size();
                channels.data =list.subList(0,size);
            }
        }
        return channels;
    }
}
